package com.bestcem.xm.member.handler;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.bestcem.xm.common.core.uitls.EnumUtil;
import com.bestcem.xm.componet.redis.service.RedisService;
import com.bestcem.xm.member.dao.ExportRecordDao;
import com.bestcem.xm.member.dao.ImportRecordDao;
import com.bestcem.xm.member.entity.pojo.ExportRecordDO;
import com.bestcem.xm.member.entity.pojo.ImportRecordDo;
import com.bestcem.xm.member.enums.ExportStatusEnum;
import com.bestcem.xm.member.enums.ImportRecordStatusEnum;
import com.bestcem.xm.member.enums.MemberTypeEnum;
import com.bestcem.xm.member.handler.imports.IndividualMemberImportHandler;
import com.bestcem.xm.member.handler.imports.InstitutionMemberImportHandler;
import com.bestcem.xm.member.handler.imports.InteriorMemberImportHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * 导入进度处理器
 *
 * @author yf.wang <yf.wang@idiaoyan.com>
 * @version V1.0
 * @date 2021/8/6
 */
@Slf4j
@Component
public class MemberImportProgressHandler {

    @Resource
    private RedisService redisService;

    @Resource
    private ImportRecordDao importRecordDao;

    @Resource
    private ExportRecordDao exportRecordDao;


    /**
     * 获取当前进度
     *
     * @param id  记录id
     * @param type 记录类型 0-导入 1-导出
     * @param attribute 联系人类型
     * @param orgId 组织id
     * @return
     */
    public Double getProgress(String id, Integer type, Integer attribute, String orgId) {
        // 从redis中获取相关key
        Object countObj = getProgressBarStatus(id, type);
        if (ObjectUtil.isNotEmpty(countObj)) {
            // redis 中存在数据
            return redisExistsProgress(countObj, id, type);
        } else {
            // redis中不存在数据
            return redisNotExistsProgress(id, type, attribute, orgId);
        }
    }

    private Object getProgressBarStatus(String id, Integer type) {
        String key = "";
        if (type == 0) {
            // member:member.import
            key = "member:member.import" + id;
        } else if (type == 1) {
            // member:member.export
            key = "member:member.export" + id;
        } else {
            return null;
        }
        return redisService.get(key);
    }

    /**
     * 使用redis中存储参数计算当前进度
     * {"complete_count": complete_count, "total_count": total_count, "last_timestamp":上次更新状态时的时间戳}
     * @param countObj
     * @param id
     * @param type
     * @return
     */
    private Double redisExistsProgress(Object countObj, String id, Integer type) {
        JSONObject countJson = JSONObject.parseObject(String.valueOf(countObj));
        if (log.isInfoEnabled()) {
            log.info("导入/导出进度为 {}", countJson.toJSONString());
        }
        Integer completeCount = countJson.getInteger("complete_count");
        if (log.isInfoEnabled()) {
            log.info("已完成数量 {}", completeCount);
        }
        Integer totalCount = countJson.getInteger("total_count");
        if (log.isInfoEnabled()) {
            log.info("总数量 {}", totalCount);
        }
        Long lastTimestamp = countJson.getLong("last_timestamp");
        if (log.isInfoEnabled()) {
            log.info("lastTimestamp {}", lastTimestamp);
        }
        // 获取当前时间zz
        Long nowTimestamp = System.currentTimeMillis();
        if (nowTimestamp - lastTimestamp > (3600 * 1000)) {
            // 上次更新数据的状态超过3600s 则设置状态为导入超时
            if (log.isInfoEnabled()) {
                log.info("上次更新数据的状态超过3600s 则设置状态为导入超时");
            }
            setOverTimeRecordStatus(id, type);
            return 1.0;
        }
        if (ObjectUtil.isEmpty(totalCount) || totalCount.equals(completeCount)) {
            return 1.0;
        } else {
            return ((completeCount * 0.1) / totalCount) * 10;
        }
    }

    /**
     * redis中不存在数据时计算方式
     *
     * @param id
     * @param type
     * @param attribute
     * @param orgId
     * @return
     */
    private Double redisNotExistsProgress(String id, Integer type, Integer attribute, String orgId) {
        if (type == 0) {
            ImportRecordDo importRecord = importRecordDao.findOneById(id);
            if (ObjectUtil.isNotEmpty(importRecord)) {
                Integer status = importRecord.getStatus();
                // 状态为成功或者失败均返回100%
                if (status == ImportRecordStatusEnum.IMPORT_RECORD_STATUS_SUCCESS.getIndex() ||
                        status == ImportRecordStatusEnum.IMPORT_RECORD_STATUS_FAILED.getIndex()) {
                    return 1.0;
                } else {
                    String key = "";
                    // 判断是否有正在导入的任务
                    switch (EnumUtil.getEnumByIndex(MemberTypeEnum.class, attribute)) {
                        case INDIVIDUAL:
                            key = new IndividualMemberImportHandler().genImportLockKey(orgId);
                            break;
                        case INSTITUTION:
                            key = new InstitutionMemberImportHandler().genImportLockKey(orgId);
                            break;
                        case INTERIOR:
                            key = new InteriorMemberImportHandler().genImportLockKey(orgId);
                            break;
                        default:
                            key = "";
                    }
                    if (redisService.hasKey(key)) {
                        return 0.0;
                    } else {
                        return 1.0;
                    }
                }
            } else {
                return 1.0;
            }
        }  else {
            ExportRecordDO exportRecord = exportRecordDao.findById(orgId, id);
            if (ObjectUtil.isNotEmpty(exportRecord)) {
                Integer status = exportRecord.getStatus();
                // 状态为成功或者失败均返回100%
                if (status == ExportStatusEnum.SUCCESS.getIndex() ||
                        status == ExportStatusEnum.FAILED.getIndex()) {
                    return 1.0;
                } else {
                    return 0.0;
                }
            } else {
                return 1.0;
            }
        }
    }

    /**
     * 更新记录状态
     *
     * @param id
     * @param type
     */
    private void setOverTimeRecordStatus(String id, Integer type) {
        if (type == 0) {
            String totalErrorMsg = new JSONObject().put("-1", "导入失败").toString();
            // 更新导入记录状态为导入失败
            importRecordDao.updateRecordStatus(id, ImportRecordStatusEnum.IMPORT_RECORD_STATUS_FAILED.getIndex());
        } else if (type == 1) {
            // 导出超时时更新导入记录状态为导入失败
            exportRecordDao.updateStatusAndMsgById(id, ExportStatusEnum.FAILED.getIndex(), "导出失败");
        }
    }
}
